﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using AAA.Algorithm.Data;

namespace AAA.Algorithm.Cluster.HSFC
{
    public class HSFCSimilarity : ISimilarity
    {
        private IFutureGroup _futureGroup;
        private IWeight _weight;
        private Dictionary<string, List<float>> _dicSimilarity;

        public HSFCSimilarity(IFutureGroup futureGroup, IWeight weight)
        {
            _futureGroup = futureGroup;
            _weight = weight;
            _dicSimilarity = new Dictionary<string, List<float>>();
        }

        #region ISimilarity Members
        private float SubSimilarity(AAA.Algorithm.Data.INeuron sourceNeuron, AAA.Algorithm.Data.INeuron compareNeuron, List<string> lstFutureName)
        {            
            float fSimilarity = 0;

            try
            {
                foreach (string strGroupName in lstFutureName)
                {
                    if (_futureGroup.IsParentNode(strGroupName))
                        fSimilarity += SubSimilarity(sourceNeuron, compareNeuron, _futureGroup.GetFuture(strGroupName)) * _weight.GetFactorWeight(strGroupName);

                    fSimilarity += ((sourceNeuron.GetFactor(strGroupName) * compareNeuron.GetFactor(strGroupName) < 0)
                                    ? 0
                                    : Math.Min(Math.Abs(sourceNeuron.GetFactor(strGroupName)), Math.Abs(compareNeuron.GetFactor(strGroupName))) /
                                        Math.Max(Math.Abs(sourceNeuron.GetFactor(strGroupName)), Math.Abs(compareNeuron.GetFactor(strGroupName)))) * _weight.GetFactorWeight(strGroupName);
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message + "," + ex.StackTrace);
            }
            return fSimilarity;
        }

        public float Similarity(AAA.Algorithm.Data.INeuron sourceNeuron, AAA.Algorithm.Data.INeuron compareNeuron)
        {
            try
            {
                return SubSimilarity(sourceNeuron, compareNeuron, _futureGroup.GetFuture(_futureGroup.RootName));
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message + "," + ex.StackTrace);
            }
            return float.NaN;
        }

        #endregion
    }
}
